import {arrayMethods} from '../observer/array'
import Dep from './dep'

class Observer{
    constructor(value){
        // value.__ob__ = this  //数组的__ob__属性执行Observer实例
        Object.defineProperty(value,'__ob__',{  
            value:this,
            enumerable:false,  //不会被遍历
            configurable:false //不能被删除
         }) 
        if(Array.isArray(value)){
            //设置数组的__proto__ 指向新创建的原型对象，数组只要调原型上的方法，则指向arrayMethods指定的那7个方法
            Object.setPrototypeOf(value,arrayMethods)  
            this.observeArray(value); //数组的每一项也可能是对象
            
        }else{
            this.walk(value) 
        }
    }
    walk(data){
        Object.keys(data).forEach((key)=>{
            defineReactive(data,key,data[key])  
        })
    }
    observeArray(arr){
        for(let i=0;i<arr.length;i++){
            observe(arr[i])  //观测数组的每一项
        } 
    }
}
export function observe(data){
   //只对对象类型数据进行观测，非对象类型无法观测 
    if(data == null || typeof data !='object'){
        return  
    }
    if(data.__ob__){  //如果有__ob__属性，说明观测过了，无需重复观测
        return;
    }
    return new Observer(data)   
}
//数据观测的核心方法
function defineReactive(data,key,value){
    observe(value)
    let dep = new Dep();
    Object.defineProperty(data,key,{
        get(){
            if(Dep.target){
               dep.addSub(Dep.target)  //get的时候依赖收集
            }
            console.log(Dep.target)
            return value; 
        },
        set(newValue){
            if(value == newValue){
                return; 
            }
            observe(newValue)  //如果用户设置的是一个新数据，也能进行观测
            value = newValue
            dep.notify()              //set的时候更新
            //return data[key]
        }
    })
}
export default Observer